/**
 * Copyright 2018 人人开源 http://www.renren.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package cn.yi.boot.shiro.handler;

import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import yi.boot.common.exception.BusinessException;
import yi.boot.common.response.R;

import java.util.List;

/**
 * 异常处理器
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2016-10-27
 */
@RestControllerAdvice
public class BootExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(BusinessException.class)
    public R handleRRException(BusinessException e) {
        R r = new R();
        r.setCode(e.getCode());
        r.setMessage(e.getMessage());

        return r;
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public R handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error(e.getMessage(), e);
        return R.error("数据库中已存在该记录");
    }

    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public R handleMethodArgumentNotValidException(Exception e) {
        logger.error(e.getMessage(), e);
        List<FieldError> errors = null;
        if (e instanceof BindException) {
            errors = ((BindException) e).getFieldErrors();
        } else if (e instanceof MethodArgumentNotValidException) {
            errors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors();
        }
        if (CollectionUtils.isNotEmpty(errors)) {
            return R.error(errors.get(0).getDefaultMessage());
        }
        return R.error("系统异常");
    }


    @ExceptionHandler(AuthorizationException.class)
    public R handleAuthorizationException(AuthorizationException e) {
        logger.error(e.getMessage(), e);
        return R.error("没有权限，请联系管理员授权");
    }

    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        logger.error(e.getMessage(), e);
        return R.error(e.getMessage());
    }
}
